(ns #^{:doc "Responsible for starting/stopping the Jtacck web server
            as well as defining the Jetty application."}
    clj.jtacck.web.core
  (:use [clj.jtacck.web.templates]
	[compojure.core :only [GET POST ANY defroutes]]
	[ring.adapter.jetty :only [run-jetty]]
	[hiccup.core :only [html]]
	[ring.util.response :only [response resource-response redirect status]]
	[ring.middleware.session :only [wrap-session]]
	[compojure.handler :only [site]])
  (:require [compojure.route :as route]
	    [clojure.contrib.pprint :as pprint] ; DEBUG printing
	    [clj.jtacck.logging :as log]))


(defroutes main-routes
  #_(ANY "*" map (do (pprint/pprint map) :next)) ;; DEBUG printing
  (ANY "*" map (do (log/finest (str "Access of uri: " (:uri map))) :next))

  ;;; Block access to any directories
  (ANY "/*/" {uri :uri} (access-denied uri))
  
  ;;; Static resources (img/css/js)
  (route/resources "/css/" {:root "web/public/css"})
  (route/resources "/js/" {:root "web/public/js"})
  (route/resources "/img/" {:root "web/public/img"})

  ;;; User login/logout
  (GET "/login" [] (login-page))
  (POST "/login" {{submit :pclc_submit
		   pass :pclc_password
		   user :pclc_user_name} :params
		   session :session}
	(if-not (= submit "Login")
	  :next
	  (login-page session user pass)))
  ;; User must login first before going further.
  (ANY "*" {{logged-in? :user-info} :session}
       (if logged-in?
	 :next
	 (redirect "/login")))
  (ANY "/logout" {session :session}
       (-> (redirect "/login")
	   (assoc :session (dissoc session :user-info))))

  ;;; Dynamic Pages
  (GET "/" {:keys [session]} (index-page (:user-info session)))

  ;;; Form Post Pages
  (POST "/add/shipment" {:keys [session params]}
	(add-shipment-page params session))
  (POST "/add/user" {:keys [session params]}
	(add-user-page params session))
  (POST "/add/route" {:keys [session params]} ; TODO Rename to /change
	(set-route-page params session))
  (POST "/add/clientsite" {:keys [session params]}
	(add-client-site-page params session))
  (POST "/add/hospital" {:keys [session params]}
	(add-hospital-page params session))

  (POST "/change/startingChecklist" {:keys [session params]}
	(set-starting-checklist-page params session))
  (POST "/change/endingChecklist" {:keys [session params]}
	(set-ending-checklist-page params session))
  
  (POST "/scan/labBarcodeScan" {:keys [session params]}
	(lab-barcode-scan-page params session))

  (GET "/get/clientSiteChecklist" {:keys [session params]}
	(get-client-checklist-table params session))
  
  ;;; Dynamic Resources (images/etc.)
  (GET "/lab-graph.png" []  (get-graph))

  ;;; Test Pages
  (GET "/session" {session :session}
       (html [:html
	      [:head [:title "Session Information"]]
	      [:body
	       [:h1 "Session Information"]
	       [:pre (pprint/write session :stream nil)]]]))

  ;;; Check for a static HTML page.
  (GET "/*" {uri :uri} (or (resource-response (str (subs uri 1) ".html")
					      {:root "web/public"})
			   :next))
  
  ;;; Fall-through 404 page.
  (ANY "*" [:as {:keys [uri]}] (not-found uri)))


(def #^{:doc "The main application for Jetty."}
     app (-> main-routes
	     site)) ;;; Wrap for params/sessions

(defonce ^{:private true} server (atom nil))

(defn start-server
  "Starts the Jetty web server asynchronously on the given port. If
  already started, does nothing."
  [port]
  (if-not @server
    (do
      (reset! server (doto (run-jetty app {:port port :join? false}) .start))
      true)
    false))
  ;;:ssl-port 8443 :keystore "jtacck.keystore" :key-password "7t@(Ck" ;; TODO SSL

(defn stop-server
  "Stops the Jetty web server if started."
  []
  (if @server
    (do
      (swap! server (fn [_] (do (.stop @server) nil)))
      true)
    false))